gl: Track the current uniform state for custom programs
authorAlexander Larsson <alexl@redhat.com>
Tue, 29 Sep 2020 09:52:39 +0000 (11:52 +0200)
committerAlexander Larsson <alexl@redhat.com>
Tue, 29 Sep 2020 09:52:39 +0000 (11:52 +0200)
This allows us to avoid updating uniforms if that is not necessary. This
in turn allows us to sometimes reuse the same draw op by just extending the
vertex array size we draw rather than doing a separate glDraw call.

For example, in the fishbowl demo, all the icons added at the same
time will have the same time and size, so we emit single draw calls
with 100s of triangles instead of 100s of draw calls with 2 triangles.

gsk/gl/gskglrenderops.c
gsk/gl/gskglrenderopsprivate.h

index 1fc9d02810c8869d0c48abda1317084530e07e1a..63273db93d04a8119b23546c644653db48b869f4 100644 (file)
@@ -640,7 +640,28 @@ ops_set_gl_shader_args (RenderOpBuilder       *builder,
                         float                  height,
                         const guchar          *uniform_data)
 {
+  ProgramState *current_program_state = get_current_program_state (builder);
   OpGLShader *op;
+  gsize args_size = gsk_gl_shader_get_args_size (shader);
+
+  if (current_program_state)
+    {
+      if (current_program_state->gl_shader.width == width &&
+          current_program_state->gl_shader.height == height &&
+          current_program_state->gl_shader.uniform_data_len == args_size &&
+          memcmp (current_program_state->gl_shader.uniform_data, uniform_data, args_size) == 0)
+        return;
+
+      current_program_state->gl_shader.width = width;
+      current_program_state->gl_shader.height = height;
+      if (args_size > sizeof (current_program_state->gl_shader.uniform_data))
+        current_program_state->gl_shader.uniform_data_len = 0;
+      else
+        {
+          current_program_state->gl_shader.uniform_data_len = args_size;
+          memcpy (current_program_state->gl_shader.uniform_data, uniform_data, args_size);
+        }
+    }
 
   op = ops_begin (builder, OP_CHANGE_GL_SHADER_ARGS);
   op->shader = shader;
index 38b5756a9c722e8e8d0e4d4965091ed89ad6283b..6f90a0c2126f6ef292073289fe8bcb8dfebacb26 100644 (file)
@@ -79,6 +79,12 @@ typedef struct
       float end;
       float radius[2]; /* h/v */
     } radial_gradient;
+    struct {
+      float width;
+      float height;
+      gint uniform_data_len;
+      guchar uniform_data[32];
+    } gl_shader;
   };
 } ProgramState;